/**
 * PHOSIDE: PHosphorylation Site IDentification Engine.
 * Copyright 2009 Digital Biology Lab, University of Missouri.
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 3 of the License, or (at your option) any later
 * version. <p/> This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more
 * details.
 */

package phoside.io.xml;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;

import org.apache.commons.lang.StringEscapeUtils;

import phoside.Protein;
import phoside.Proteins;

import phoside.io.ProteinsWriter;

/**
 *
 * @author gjj
 */
public class PhosideXmlProteinsWriter implements ProteinsWriter {
    protected final String dirOut;
    protected final Set<String> proteinFieldFilter;
    protected final boolean proteinFieldInclude;
    protected final ProteinFieldValueFormatter formatter;

    public PhosideXmlProteinsWriter(final String dirOut) {
        this (dirOut, new DefaultProteinFieldValueFormatter()); // include all
    }

    public PhosideXmlProteinsWriter(final String dirOut,
           final ProteinFieldValueFormatter formatter) {
        this (dirOut, formatter, null);
    }

    public PhosideXmlProteinsWriter(final String dirOut,
           final ProteinFieldValueFormatter formatter,
           final Set<String> proteinFieldFilter) {
        this (dirOut, formatter, proteinFieldFilter,true);
    }

    public PhosideXmlProteinsWriter(final String dirOut,
           final ProteinFieldValueFormatter formatter,
           final Set<String> proteinFieldFilter,
           final boolean proteinFieldInclude) {
        this.dirOut = dirOut;
        this.proteinFieldFilter = proteinFieldFilter;
        this.proteinFieldInclude = proteinFieldInclude;
        this.formatter = formatter;
    }

    /**
     * {@inheritDoc}
     */
    public void write(Proteins data) throws IOException {
        if (data==null) {
            throw new IllegalArgumentException();
        }

        FileWriter fout = new FileWriter(dirOut);
        BufferedWriter out = new BufferedWriter(fout);

        out.write("<?xml version=\"1.0\" encoding='UTF-8'?>");
        out.newLine();

        out.write("<phoside>");
        out.newLine();

        Iterator<Protein> it = data.proteinIterator();
        while (it.hasNext()) {
            Protein protein = it.next();
            out.write("<protein>");
            out.newLine();

            TreeMap<String, Object> infoMap = new TreeMap(protein.getInfoMap());

            for (String field : infoMap.keySet()) {
                if (proteinFieldFilter!=null &&
                        proteinFieldFilter.contains(field)!=proteinFieldInclude)
                    continue;
                
                Object value = infoMap.get(field);
                if (value==null)
                    continue;

                String formated = formatter.write(field, value);
                if (formated!=null) {
                    out.write("\t<"+field+">");
                    out.write(StringEscapeUtils.escapeXml(formated));
                    out.write("</"+field+">");
                    out.newLine();
                }
            }

            out.write("</protein>");
            out.newLine();
        }

        out.write("</phoside>");
        out.newLine();

        out.close();
        fout.close();
    }
}
